const dayjs = require('dayjs');
import Day from 'dayjs';
import BaseModel from './base_model';

/**
 * 任务领域模型
 * 封装任务业务逻辑与规则
 */
class TaskModel extends BaseModel {
  constructor(data = {}) {
    super(data);
    // 基本属性
    this._id = data._id || '';
    this.projectId = data.projectId || '';
    this.projectName = data.projectName || '';
    this.title = data.title || '';
    this.description = data.description || '';
    this.assigneeId = data.assigneeId || '';
    this.assigneeName = data.assigneeName || '';
    this.creatorId = data.creatorId || '';
    this.creatorName = data.creatorName || '';
    this.status = data.status || 0;
    this.priority = data.priority || 2;
    this.startDate = data.startDate || '';
    this.dueDate = data.dueDate || null;
    this.completedDate = data.completedDate || '';
    this.category = data.category || '';
    this.tags = data.tags || [];
    this.attachments = data.attachments || [];
    this.subtasks = data.subtasks || [];
    this.comments = data.comments || [];
    this.dependencies = data.dependencies || [];
    this.watchers = data.watchers || [];
    this.estimatedHours = data.estimatedHours || 0;
    this.actualHours = data.actualHours || 0;
    this.relatedResources = data.relatedResources || [];
    this.createTime = data.createTime || dayjs().valueOf();
    this.updateTime = data.updateTime || this.createTime;
    
    // 计算属性
    this.isOverdue = this._calculateIsOverdue();
    this.daysLeft = this._calculateDaysLeft();
    this.progress = this._calculateProgress();
    this.isBlocked = this._checkIfBlocked();
  }
  
  /**
   * 计算任务是否过期
   */
  _calculateIsOverdue() {
    if (!this.dueDate) return false;
    return Day().isAfter(Day(this.dueDate)) && this.status !== 'completed' && this.status !== 'cancelled';
  }
  
  /**
   * 计算剩余天数
   */
  _calculateDaysLeft() {
    if (!this.dueDate) return null;
    if (this.status === 'completed' || this.status === 'cancelled') return 0;
    
    const today = Day();
    const due = Day(this.dueDate);
    return Math.max(0, due.diff(today, 'day'));
  }
  
  /**
   * 计算任务进度
   */
  _calculateProgress() {
    if (this.status === 'completed') return 100;
    if (this.status === 'pending') return 0;
    
    // 根据子任务计算进度
    if (this.subtasks && this.subtasks.length > 0) {
      const completed = this.subtasks.filter(task => task.status === 'completed').length;
      return Math.round((completed / this.subtasks.length) * 100);
    }
    
    // 默认进度
    return this.status === 'in_progress' ? 50 : 0;
  }
  
  /**
   * 检查任务是否被阻塞
   */
  _checkIfBlocked() {
    return this.status === 'blocked' || 
           (this.dependencies && 
            this.dependencies.some(dep => dep.status !== 'completed'));
  }
  
  /**
   * 获取任务状态文本
   */
  getStatusText() {
    const statusMap = {
      'pending': '待处理',
      'in_progress': '进行中',
      'completed': '已完成',
      'cancelled': '已取消',
      'blocked': '被阻塞',
      'reviewing': '审核中',
      'approved': '已审核',
      'rejected': '已拒绝'
    };
    
    return statusMap[this.status] || '未知状态';
  }
  
  /**
   * 获取优先级文本
   */
  getPriorityText() {
    const priorityMap = {
      'low': '低',
      'normal': '中',
      'high': '高',
      'urgent': '紧急'
    };
    
    return priorityMap[this.priority] || '中';
  }
  
  /**
   * 更新任务状态
   * @param {String} newStatus 新状态
   * @param {String} userId 操作用户ID
   * @returns {Object} 更新结果
   */
  updateStatus(newStatus, userId) {
    const oldStatus = this.status;
    this.status = newStatus;
    
    // 如果标记为完成，设置完成日期
    if (newStatus === 'completed' && !this.completedDate) {
      this.completedDate = dayjs().toISOString();
    }
    
    // 记录状态变更历史
    const statusChange = {
      time: dayjs().valueOf(),
      userId: userId,
      oldStatus: oldStatus,
      newStatus: newStatus
    };
    
    this.statusHistory = this.statusHistory || [];
    this.statusHistory.push(statusChange);
    
    // 更新进度
    this.progress = this._calculateProgress();
    
    return {
      success: true,
      message: `任务状态已从"${this.getStatusText(oldStatus)}"更新为"${this.getStatusText(newStatus)}"`
    };
  }
  
  /**
   * 添加子任务
   * @param {Object} subtask 子任务对象
   */
  addSubtask(subtask) {
    if (!subtask.title) {
      return { success: false, message: '子任务标题不能为空' };
    }
    
    const newSubtask = {
      id: `subtask_${dayjs().valueOf()}`,
      title: subtask.title,
      status: subtask.status || 'pending',
      createTime: dayjs().valueOf()
    };
    
    this.subtasks = this.subtasks || [];
    this.subtasks.push(newSubtask);
    
    // 更新进度
    this.progress = this._calculateProgress();
    
    return { success: true, subtaskId: newSubtask.id };
  }
  
  /**
   * 添加评论
   * @param {String} content 评论内容
   * @param {String} userId 用户ID
   * @param {String} userName 用户名
   */
  addComment(content, userId, userName) {
    if (!content) {
      return { success: false, message: '评论内容不能为空' };
    }
    
    const newComment = {
      id: `comment_${dayjs().valueOf()}`,
      content,
      userId,
      userName,
      createTime: dayjs().valueOf()
    };
    
    this.comments = this.comments || [];
    this.comments.push(newComment);
    
    return { success: true, commentId: newComment.id };
  }
  
  /**
   * 转换为存储格式
   */
  toStorage() {
    const data = {...this};
    
    // 处理日期
    if (data.startDate && typeof data.startDate === 'string') {
      data.startDate = Day(data.startDate).valueOf();
    }
    
    if (data.dueDate && typeof data.dueDate === 'string') {
      data.dueDate = Day(data.dueDate).valueOf();
    }
    
    if (data.completedDate && typeof data.completedDate === 'string') {
      data.completedDate = Day(data.completedDate).valueOf();
    }
    
    return data;
  }
  
  /**
   * 验证任务数据是否有效
   */
  validate() {
    const errors = {};
    
    if (!this.title) errors.title = '任务标题不能为空';
    if (!this.projectId) errors.projectId = '项目ID不能为空';
    
    // 如果设置了开始日期和截止日期，确保开始日期早于截止日期
    if (this.startDate && this.dueDate) {
      if (Day(this.startDate).isAfter(Day(this.dueDate))) {
        errors.dateRange = '开始日期不能晚于截止日期';
      }
    }
    
    // 验证子任务
    if (this.subtasks && this.subtasks.length > 0) {
      const invalidSubtasks = this.subtasks.filter(task => !task.title);
      if (invalidSubtasks.length > 0) {
        errors.subtasks = '子任务标题不能为空';
      }
    }
    
    return {
      valid: Object.keys(errors).length === 0,
      errors
    };
  }

  updateDeadline(dueDate) {
    this.dueDate = dueDate;
    this.modified = {
      ...this.modified,
      time: dayjs().valueOf(),
      fields: [...(this.modified?.fields || []), 'dueDate']
    };
    return this;
  }
}

export default TaskModel; 